﻿@page "/"
@using ComputerLock.Resources
@using ComputerLock.Enums
@using ComputerLock.Hooks
@using ComputerLock.Platforms
@using JiuLing.CommonLibs.ExtensionMethods
@using JiuLing.CommonLibs.Log
@using JiuLing.CommonLibs.Text

@inject AppSettings AppSettings
@inject AppSettingWriter AppSettingWriter
@inject IStringLocalizer<Lang> Lang
@inject ISnackbar Snackbar
@inject IDialogService Dialog
@inject UpdateHelper UpdateHelper
@inject ILocker Locker
@inject KeyboardHook KeyboardHook
@inject IWindowTitleBar WindowTitleBar
@inject ILogger Logger;

<style>
    .dialog-blurry {
        backdrop-filter: blur(10px);
    }
</style>

<MudSwitch @bind-Checked="@(AppSettings.IsDisableWindowsLock)"
           @bind-Checked:after="SaveSettings"
           Label="@(Lang["DisableWindowsLock"])"
           Color="Color.Primary" />

<MudSwitch @bind-Checked="@(AppSettings.LockAnimation)"
           @bind-Checked:after="SaveSettings"
           Label="@(Lang["LockAnimation"])"
           Color="Color.Primary" />

<div class="d-flex align-center">
    <MudSwitch @bind-Checked="@(AppSettings.EnablePasswordBox)"
               @bind-Checked:after="SaveSettings"
               Label="@(Lang["EnablePasswordBox"])"
               Color="Color.Primary" />
    @if (!AppSettings.EnablePasswordBox)
    {
        <MudChip Label="true"
                 Icon="@Icons.Material.Filled.WarningAmber"
                 IconColor="Color.Primary"
                 DisableRipple="true"
                 Size="Size.Small">
            @(Lang["EnablePasswordBoxTips"])
        </MudChip>
    }
</div>

<MudSwitch @bind-Checked="@(AppSettings.IsHidePasswordWindow)"
           @bind-Checked:after="SaveSettings"
           Class="ml-6"
           Disabled="@(!AppSettings.EnablePasswordBox)"
           Label="@(Lang["HidePasswordWindow"])"
           Color="Color.Primary" />

<MudSwitch @bind-Checked="@(_keyboardDownChecked)"
           @bind-Checked:after="KeyboardDownChecked"
           Class="ml-6"
           Disabled="@(!AppSettings.EnablePasswordBox)"
           Label="@(Lang["KeyboardDownActivePwd"])"
           Color="Color.Primary" />

<MudSwitch @bind-Checked="@(_mouseDownChecked)"
           @bind-Checked:after="MouseDownChecked"
           Class="ml-6"
           Disabled="@(!AppSettings.EnablePasswordBox)"
           Label="@(Lang["MouseDownActivePwd"])"
           Color="Color.Primary" />

<div class="d-flex align-center mt-2">
    <MudText Typo="Typo.button">@(Lang["LockShortcutKey"])</MudText>
    <MudButton Class="ml-3"
               Variant="Variant.Text"
               Size="Size.Small"
               Color="Color.Primary"
               OnClick="SetShortcutKey">
        @(_shortcutKeyText)
    </MudButton>
    @if (AppSettings.ShortcutKeyForLock.IsNotEmpty())
    {
        <MudTooltip Text="删除快捷键" Delay="600">
            <MudIconButton Icon="@Icons.Material.Filled.Delete"
                           Size="Size.Small"
                           OnClick="ClearShortcutKey" />
        </MudTooltip>
    }
</div>

<MudGrid>
    <MudItem xs="6">
        <MudSelect T="int"
                   Label="@(Lang["AutoLock"])"
                   Value="@(AppSettings.AutoLockSecond)"
                   Class="mt-4"
                   ValueChanged="AutoLockChanged"
                   Dense="true">
            <MudSelectItem Value="0">@(Lang["Never"])</MudSelectItem>
            <MudSelectItem Value="60">@(Lang["Minute1"])</MudSelectItem>
            <MudSelectItem Value="120">@(Lang["Minute2"])</MudSelectItem>
            <MudSelectItem Value="180">@(Lang["Minute3"])</MudSelectItem>
            <MudSelectItem Value="300">@(Lang["Minute5"])</MudSelectItem>
            <MudSelectItem Value="600">@(Lang["Minute10"])</MudSelectItem>
        </MudSelect>
    </MudItem>
    <MudItem xs="6">
        <MudSelect T="ScreenLocationEnum"
                   Label="@(Lang["PwdLocation"])"
                   Value="@(AppSettings.PasswordInputLocation)"
                   Class="mt-4"
                   ValueChanged="PwdBoxLocationChanged"
                   Dense="true">
            <MudSelectItem Value="@(ScreenLocationEnum.Center)">@(Lang["Center"])</MudSelectItem>
            <MudSelectItem Value="@(ScreenLocationEnum.TopLeft)">@(Lang["TopLeft"])</MudSelectItem>
            <MudSelectItem Value="@(ScreenLocationEnum.TopRight)">@(Lang["TopRight"])</MudSelectItem>
            <MudSelectItem Value="@(ScreenLocationEnum.BottomLeft)">@(Lang["BottomLeft"])</MudSelectItem>
            <MudSelectItem Value="@(ScreenLocationEnum.BottomRight)">@(Lang["BottomRight"])</MudSelectItem>
        </MudSelect>
    </MudItem>
</MudGrid>

<div class="d-flex align-center mt-4">
    <MudButton Class="mr-3"
               Variant="Variant.Text"
               Size="Size.Small"
               Color="Color.Primary"
               OnClick="SetPassword">
        @(Lang["SetPassword"])
    </MudButton>
    @if (!AppSettings.IsPasswordChanged)
    {
        <MudText Typo="Typo.caption">@(Lang["PasswordTip"])</MudText>
    }
</div>

@code {

    private bool _keyboardDownChecked;
    private bool _mouseDownChecked;
    private string _shortcutKeyText = "未设置";
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        _keyboardDownChecked = (AppSettings.PasswordBoxActiveMethod & PasswordBoxActiveMethodEnum.KeyboardDown) == PasswordBoxActiveMethodEnum.KeyboardDown;
        _mouseDownChecked = (AppSettings.PasswordBoxActiveMethod & PasswordBoxActiveMethodEnum.MouseDown) == PasswordBoxActiveMethodEnum.MouseDown;
        UpdateShortcutKeyForLock();

        KeyboardHook.KeyPressed += _keyboardHook_KeyPressed;

        if (AppSettings.IsAutoCheckUpdate)
        {
            await UpdateHelper.DoAsync(true);
        }
    }

    private void _keyboardHook_KeyPressed(object sender, KeyPressedEventArgs e)
    {
        Logger.Write("快捷键解锁");
        Locker.Lock();
    }

    private void KeyboardDownChecked()
    {
        if (!_keyboardDownChecked)
        {
            if (!_mouseDownChecked)
            {
                _keyboardDownChecked = true;
                Snackbar.Add(Lang["ActiveMethodEmpty"], Severity.Warning);
                return;
            }
        }
        SavePasswordBoxActiveMethod();
    }
    private void MouseDownChecked()
    {
        if (!_mouseDownChecked)
        {
            if (!_keyboardDownChecked)
            {
                _mouseDownChecked = true;
                Snackbar.Add(Lang["ActiveMethodEmpty"], Severity.Warning);
                return;
            }
        }
        SavePasswordBoxActiveMethod();
    }

    private void SavePasswordBoxActiveMethod()
    {
        AppSettings.PasswordBoxActiveMethod = 0;
        if (_keyboardDownChecked)
        {
            AppSettings.PasswordBoxActiveMethod |= PasswordBoxActiveMethodEnum.KeyboardDown;
        }
        if (_mouseDownChecked)
        {
            AppSettings.PasswordBoxActiveMethod |= PasswordBoxActiveMethodEnum.MouseDown;
        }
        SaveSettings();
    }

    private void AutoLockChanged(int autoLockSecond)
    {
        AppSettings.AutoLockSecond = autoLockSecond;
        SaveSettings();
        RestartTips();
    }

    private void PwdBoxLocationChanged(ScreenLocationEnum location)
    {
        AppSettings.PasswordInputLocation = location;
        SaveSettings();
        RestartTips();
    }
    private void RestartTips()
    {
        Snackbar.Configuration.NewestOnTop = true;
        Snackbar.Configuration.VisibleStateDuration = int.MaxValue;
        Snackbar.Configuration.ShowCloseIcon = true;
        Snackbar.Configuration.SnackbarVariant = Variant.Text;
        Snackbar.Add(Lang["Restarting"], Severity.Normal, config =>
        {
            config.Action = Lang["Restart"];
            config.HideIcon = true;
            config.ActionColor = Color.Warning;
            config.ActionVariant = Variant.Outlined;
            config.Onclick = snackbar =>
            {
                Restart();
                return Task.CompletedTask;
            };
        });
    }

    private void Restart()
    {
        WindowTitleBar.Restart();
    }

    private void SaveSettings()
    {
        AppSettingWriter.Save(AppSettings);
    }
    private async Task SetShortcutKey()
    {
        var noHeader = new DialogOptions()
            {
                NoHeader = true,
                ClassBackground = "dialog-blurry",
                CloseOnEscapeKey = false,
            };
        var dialog = await Dialog.ShowAsync<ShortcutKeySetting>("", noHeader);
        var result = await dialog.Result;
        if (result.Canceled)
        {
            return;
        }

        var shortcutKeyModel = result.Data as ShortcutKeyModel;
        if (shortcutKeyModel == null)
        {
            return;
        }

        AppSettings.ShortcutKeyForLock = shortcutKeyModel.ShortcutKey;
        AppSettings.ShortcutKeyDisplayForLock = shortcutKeyModel.ShortcutKeyDisplay;
        SaveSettings();
        UpdateShortcutKeyForLock();
    }
    private async Task ClearShortcutKey()
    {
        AppSettings.ShortcutKeyForLock = "";
        AppSettings.ShortcutKeyDisplayForLock = "";
        SaveSettings();
        UpdateShortcutKeyForLock();
    }

    public void UpdateShortcutKeyForLock()
    {
        if (AppSettings.ShortcutKeyForLock.IsEmpty())
        {
            try
            {
                Logger.Write("释放锁屏热键");
                KeyboardHook.UnregisterHotKey();
            }
            catch (Exception ex)
            {
                Logger.Write($"释放锁屏热键失败：{ex.Message}。{ex.StackTrace}");
                //MessageBoxUtils.ShowError($"取消快捷键失败：{ex.Message}");
            }
            _shortcutKeyText = Lang["Invalid"];
        }
        else
        {
            try
            {
                ModifierKeys keys = 0;
                if (AppSettings.ShortcutKeyForLock.IndexOf("Ctrl") >= 0)
                {
                    keys = keys | Hooks.ModifierKeys.Control;
                }
                if (AppSettings.ShortcutKeyForLock.IndexOf("Shift") >= 0)
                {
                    keys = keys | Hooks.ModifierKeys.Shift;
                }
                if (AppSettings.ShortcutKeyForLock.IndexOf("Alt") >= 0)
                {
                    keys = keys | Hooks.ModifierKeys.Alt;
                }

                var result = RegexUtils.GetFirst(AppSettings.ShortcutKeyForLock, @"\d+");
                if (result.success == false)
                {
                    throw new Exception(Lang["ShortcutKeyConfigError"]);
                }
                Logger.Write("注册锁屏热键");
                Keys key = (Keys)Convert.ToInt32(result.result);
                KeyboardHook.RegisterHotKey(keys, key);

                _shortcutKeyText = AppSettings.ShortcutKeyDisplayForLock;
            }
            catch (Exception ex)
            {
                Logger.Write($"绑定锁屏热键失败：{ex.Message}。{ex.StackTrace}");
                Snackbar.Add($"{Lang["ExRegistFailed"]}{ex.Message}", Severity.Error);
            }
        }
    }


    private async Task SetPassword()
    {
        var noHeader = new DialogOptions()
            {
                ClassBackground = "dialog-blurry",
                CloseOnEscapeKey = false,
                CloseButton = true
            };
        var dialog = await Dialog.ShowAsync<SetPassword>(Lang["SetPassword"], noHeader);
        var result = await dialog.Result;
        if (result.Canceled)
        {
            return;
        }
        if (result.Data == null)
        {
            return;
        }
        AppSettings.Password = result.Data.ToString();
        AppSettings.IsPasswordChanged = true;
        SaveSettings();
    }
}